﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HalconDotNet;
using Project1.Common;
using Project1.Interface;
namespace Project1.Element
{
    public class SupportLine : Line
    {
        /// <summary>
        /// line派生类，辅助线功能,并显示数值（例如距离)
        /// </summary>
        private double rowOffset, columnOffset;
        private double value;
        private Point p1;
        private Point p2;
        private Point currentP1;
        private Point currentP2;
        private bool isSelected = false;
        public delegate void SetSelectedItem(string mode, SupportLine line = null);

        public void SetValue(double value)
        {
            this.value = value;
        }

        public void SetOffset(double rowOffset,double columnOffset)
        {
            this.rowOffset = rowOffset;
            this.columnOffset = columnOffset;
        }
        public double RowOffset { get{ return rowOffset; }}
        public double ColumnOffset { get { return columnOffset; } }


        public SupportLine()
        {

        }

        public SupportLine(Point startPoint, Point endPoint, string name, HObject lineContours)
        {
            this.lineContours = lineContours;
            HOperatorSet.GenRegionContourXld(lineContours, out region, "filled");
            HOperatorSet.DilationCircle(region, out region, 10);
            this.startPoint = new Point(startPoint);
            this.endPoint = new Point(endPoint);
            //this.drawingObjectID = drawingObjectID;
            this.name = name;
            this.length = startPoint.Distance(endPoint);
        }

        public SupportLine(Point startPoint, Point endPoint)
        {
            double[] rows = { startPoint.Row, endPoint.Row };
            double[] cols = { startPoint.Column, endPoint.Column };
            p1 = new Point(startPoint);
            p2 = new Point(endPoint);
            currentP1 = new Point(startPoint);
            currentP2 = new Point(endPoint);
            HTuple hv_Rows = new HTuple(rows);
            HTuple hv_Columns = new HTuple(cols);
            HOperatorSet.GenContourPolygonXld(out this.lineContours, hv_Rows, hv_Columns);
            HOperatorSet.GenRegionContourXld(lineContours, out region, "filled");
            HOperatorSet.DilationCircle(region, out region, 10);
            this.startPoint = new Point(startPoint);
            this.endPoint = new Point(endPoint);
            //this.drawingObjectID = drawingObjectID;
            this.length = startPoint.Distance(endPoint);
        }
        public SupportLine(SupportLine line)
        {
            lineContours = new HObject(line.lineContours);
            region = new HObject(line.region);
            rowOffset = line.rowOffset;
            columnOffset = line.columnOffset;
            startPoint = new Point(line.startPoint);
            endPoint = new Point(line.endPoint);
            //this.drawingObjectID = drawingObjectID;
            name = line.name;
            length = line.length;
        }

        public bool IsSelected
        {
            get { return isSelected; }
            set { isSelected = value; }
        }

        public SupportLine(double rowStart, double colStart, double rowEnd, double colEnd)
        {
            double[] rows = { rowStart, rowEnd };
            double[] cols = { colStart, colEnd };
            HTuple hv_Rows = new HTuple(rows);
            HTuple hv_Columns = new HTuple(cols);
            HOperatorSet.GenContourPolygonXld(out this.lineContours, hv_Rows, hv_Columns);
            HOperatorSet.GenRegionContourXld(lineContours, out region, "filled");
            HOperatorSet.DilationCircle(region, out region, 10);
            this.startPoint = new Point(rowStart, colStart, "default");
            this.endPoint = new Point(rowEnd, colEnd, "default");
            this.length = startPoint.Distance(endPoint);

        }

        public void Moving(HTuple windowHandle, out HObject transContour, out Point currentStartPoint, out Point currentEndPoint)
        {
            HTuple row = 0, column = 0, button = 0, homMat2D = 0;
            HTuple startRow = null, endRow = null;
            HTuple startCol = null, endCol = null;
            double midRow=midPoint().Row, midColumn=midPoint().Column;
            HOperatorSet.GetMposition(windowHandle, out row, out column, out button);
           
            HOperatorSet.VectorAngleToRigid(midRow, midColumn, 0, row, column, 0, out homMat2D);
            SetOffset(row - midRow, column - midColumn);
            //HOperatorSet.AffineTransContourXld(lineContours, out transContour, homMat2D);
            HOperatorSet.AffineTransPixel(homMat2D, startPoint.Row, startPoint.Column, out startRow, out startCol);
            HOperatorSet.AffineTransPixel(homMat2D, endPoint.Row, endPoint.Column, out endRow, out endCol);
            currentStartPoint = new Point(startRow, startCol);
            currentEndPoint = new Point(endRow, endCol);
            HOperatorSet.GenContourPolygonXld(out lineContours, new double[] { startRow, endRow }, new double[] { startCol, endCol });
            transContour = lineContours;
        }


        public  void InitByOffset(double rowOffset,double columnOffset, HTuple actualHomMat2D,HTuple reverseHomMat2D)
        {
            HObject transContour = null,reverseContour =null,tempContours = null;
            HTuple row = 0, column = 0, button = 0,homMat2D;
            HTuple startRow = null, endRow = null,tempStartRow,tempStartCol, tempEndRow,tempEndCol;
            HTuple startCol = null, endCol = null, tempStartRow2= null, tempStartCol2= null, tempEndRow2, tempEndCol2;
            this.rowOffset = rowOffset;
            this.columnOffset = columnOffset;
   
            double midRow = midPoint().Row, midColumn = midPoint().Column;
            
            HOperatorSet.AffineTransContourXld(lineContours, out reverseContour, reverseHomMat2D);
            HOperatorSet.AffineTransPixel(reverseHomMat2D, startPoint.Row, startPoint.Column, out tempStartRow, out tempStartCol);
            HOperatorSet.AffineTransPixel(reverseHomMat2D, endPoint.Row, endPoint.Column, out tempEndRow, out tempEndCol);

            // HOperatorSet.AffineTransPixel(reverseHomMat2D, midRow, midColumn, out reverseRow, out reverseCol);
            HOperatorSet.VectorAngleToRigid(0, 0, 0, rowOffset,columnOffset, 0, out homMat2D);

            HOperatorSet.AffineTransContourXld(reverseContour, out tempContours, homMat2D);
            HOperatorSet.AffineTransPixel(homMat2D, tempStartRow, tempStartCol, out tempStartRow2, out tempStartCol2);
            HOperatorSet.AffineTransPixel(homMat2D, tempEndRow, tempEndCol, out tempEndRow2, out tempEndCol2);

            HOperatorSet.AffineTransContourXld(tempContours, out transContour, actualHomMat2D);
            HOperatorSet.AffineTransPixel(actualHomMat2D, tempStartRow2, tempStartCol2, out startRow, out startCol);
            HOperatorSet.AffineTransPixel(actualHomMat2D, tempEndRow2, tempEndCol2, out endRow, out endCol);

         
            SetOffset(rowOffset, columnOffset);
          

            lineContours = new HObject(transContour);
            currentP1 = new Point(startRow, startCol);
            currentP2 = new Point(endRow, endCol);
        }
        public void UpdateCurrentInfo(HObject lineContours, Point currentStartPoint, Point currentEndPoint)
        {
            this.LineContours = new HObject(lineContours);
            HOperatorSet.GenRegionContourXld(lineContours, out region, "filled");
            HOperatorSet.DilationCircle(region, out region, 10);
            this.startPoint = new Point(currentStartPoint);
            this.endPoint = new Point(currentEndPoint);
        }

        public void SetCurrentPpoint(  Point currentP1, Point currentP2)
        {
            if (this.currentP1 != null) this.currentP1.Dispose();
            if (this.currentP2 != null) this.currentP2.Dispose();
            this.currentP1 = new Point(currentP1);
            this.currentP2 = new Point(currentP2);
           
        }

        public void SetPriorPoint(Point p1, Point p2)
        {
            if (this.p1 != null) this.p1.Dispose();
            if (this.p2 != null) this.p2.Dispose();
            this.p1 = new Point(p1);
            this.p2 = new Point(p2);
        }
        public void DispLine(HTuple windowHandle)
        {
            HOperatorSet.SetLineStyle(windowHandle, new HTuple(1, 4, 7, 4));
            HOperatorSet.SetColor(windowHandle, ConstValue.SUPLINE_COLOR);

            HOperatorSet.DispLine(windowHandle, p1.Row, p1.Column, currentP1.Row, currentP1.Column);
            HOperatorSet.DispLine(windowHandle, p2.Row, p2.Column, currentP2.Row, currentP2.Column);
            double midRow = 0.5 * (currentP1.Row + currentP2.Row);
            double midColumn = 0.5 * (currentP1.Column + currentP2.Column);
            HOperatorSet.SetLineStyle(windowHandle, new HTuple());
            Utils.DispMessage(windowHandle, "长度" + value, "image", midRow, midColumn, "black", "false");
         
        }


        public void BeTouched(HTuple windowHandle, SetSelectedItem method)
        {
            isSelected = isSelected == false ? true : false;
            if (isSelected)
            {
                method( "add", this);
                DispROI(windowHandle, ConstValue.SUPLINE_COLOR2);
            }
            else
            {
                method( "remove", null);
                DispROI(windowHandle, ConstValue.SUPLINE_COLOR2);
            }
        }


        public  void DispROI(HTuple windowHandle)
        {
            if (this.p1 == null || this.p2 == null || this.currentP1 == null || this.currentP2 == null) return;
            DispLine(windowHandle);
            HOperatorSet.SetColor(windowHandle, ConstValue.SUPLINE_COLOR2);
            HOperatorSet.SetDraw(windowHandle, "margin");
            HObject roi = null;
            HOperatorSet.GenRegionContourXld(lineContours, out roi, "margin");
            HOperatorSet.DispObj(roi, windowHandle);

      
        }


     

    }
}
